package cn.kingshion.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 逆波兰计算器
 */
public class PolandNotation {
    public static void main(String[] args) {
        //定义一个计算式用后缀表达式表示出来，（逆波兰表达式）
        String suffixExpression = "30 4 + 5 * 6 -";
        //用list 进行操作会比较方便
        List<String> list = getListString(suffixExpression);
        System.out.println("list:" + list);
        //调用计算方法
        int res = calculater(list);
        System.out.println("计算结果为： "+res);


    }



    /**
     * 将后缀表示分割为一个一个的操作数和操作符，并存放在list里面
     * @param suffixExpression
     * @return
     */
    public static List getListString(String suffixExpression){
        String[] spilt = suffixExpression.split(" ");
        List<String> list = new ArrayList<String >();
        for (String item:spilt) {
            list.add(item);
        }
        return list;
    }

    /**
     * 实现计算功能
     * @param list
     * @return
     */
    public static int calculater(List<String> list){
        //遍历 list 的元素，将数据入栈
        Stack<String> stack = new Stack<String>();
        for (String item:list){
            //正则表达式判断  list  里的元素是不是数字或者运算符
            if(item.matches("\\d+")){
                //如果是数字就入栈
                stack.push(item);
            }else {
                //如果是运算符就取出栈顶的数字和次栈顶的数字进行运算操作
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;
                //执行运算操作
                switch (item){
                    case "+":{
                        res = num1+num2;
                        break;
                    }
                    case "-":{
                        res = num1-num2;
                        break;
                    }
                    case "*":{
                        res = num1*num2;
                        break;
                    }
                    case "/":{
                        res = num1/num2;
                        break;
                    }
                    default:{
                        throw new RuntimeException("运算符有误");
                    }
                }
                //将运算完成后结果入栈
                stack.push("" + res);
            }
        }
        //最后留在栈底的元素就是最后运算的结果
        return Integer.parseInt(stack.pop());
    }





}
